package com.alex.megacj.mapper;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Required;

import com.alex.megacj.handler.RequestContext;

public class OneDomainURLMapper implements URLMapper {

	private long nextAlias = 1;

	private Map<String, URL> map = new HashMap<String, URL>();

	private Map<String, String> reverseMap = new HashMap<String, String>();

	@Required
	public void setDefaultURL(String url) throws MalformedURLException {
		map.put("/", new URL(url));
		reverseMap.put(url, "/");
	}

	@Override
	public boolean mapRequest(RequestContext context) throws IOException {
		String path = context.request.getRequestURI().substring(context.request.getContextPath().length());
		StringBuilder sb = new StringBuilder(path);
		if (context.request.getQueryString() != null) {
			sb.append("?").append(context.request.getQueryString());
		}
		context.targetUrlParsed = map.get(sb.toString());
		
		if (context.targetUrlParsed == null) {
			return false;
		}
		
		context.targetUrl = context.targetUrlParsed.toString();
		context.targetHost = context.targetUrlParsed.getAuthority();
		
		return true;
	}

	@Override
	public String mapURL(String url) throws MalformedURLException {
		URL parsedUrl = new URL(url);
		URL mappedUrl = map.get(parsedUrl.getFile());
		return mappedUrl != null ? mappedUrl.toExternalForm() : null;
	}
	
	@Override
	public synchronized String replaceLink(String link, RequestContext context) {
		try {
			String alias;
			if (link.startsWith("http://")) {
				alias = reverseMap.get(link);
				if (alias == null) {
					alias = createAlias(link);
				}
			} else {
				URL linkURL = new URL(context.targetUrlParsed, link);
				link = linkURL.toString();
				alias = reverseMap.get(link);
				if (alias == null) {
					alias = createAlias(linkURL, link);
				}
			}
			return "http://" + context.mirrorHost + alias;
		} catch (IOException e) {
			return link;
		}
	}

	private String createAlias(URL linkURL, String link) {
		String alias;
		String path = linkURL.getFile();
		if (!link.contains("?")) {
			int pos = path.lastIndexOf('.');
			if (pos > 0) {
				alias = path.substring(0, pos) + nextAlias + path.substring(pos);
			} else {
				alias = path + nextAlias;
			}
		} else {
			alias = path + "&" + nextAlias;
		}
		
		map.put(alias, linkURL);
		reverseMap.put(link, alias);
		
		nextAlias++;

		return alias;
	}

	private String createAlias(String link) throws MalformedURLException {
		URL url = new URL(link);
		return createAlias(url, link);
	}
}
